package com.datamigration;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import com.bss.model.Admission;
import com.bss.model.Attendent;
import com.bss.model.CurrentAttendent;
import com.bss.model.IdCardType;
import com.bss.model.MedicalProblem;
import com.bss.model.Patient;
import com.bss.model.Payment;
import com.bss.model.Place;
import com.bss.model.Profession;
import com.bss.model.Relationship;
import com.bss.model.Religion;
import com.bss.model.Room;
import com.bss.model.RoomBooking;
import com.oldbss.beans.AttendentRecord;
import com.oldbss.beans.CheckInOut;
import com.oldbss.beans.PatientRecord;
import com.oldbss.beans.Paymentsmade;
import com.oldbss.beans.RoomAllocation;

public class DataMigrationController {

	BssNew bssNew = new BssNew();
	BssOld bssOld = new BssOld();

	public void migrateData() {

		try {
			saveMasterData();
			bssNew.getEntityManager().getTransaction().begin();
			this.save();
			// bssNew.getEntityManager().flush();
			bssNew.getEntityManager().getTransaction().commit();

		} catch (Exception e) {
			e.printStackTrace();
			bssNew.getEntityManager().getTransaction().rollback();
		}

	}

	protected void saveMasterData() {
		bssNew.getEntityManager().getTransaction().begin();
		bssNew.saveProfessions();
		bssNew.saveRoomsAndBuildings();
		bssNew.saveMedicalProblems();
		bssNew.saveIdCardTypes();
		bssNew.saveRelationship();
		bssNew.savePaymentType();
		bssNew.saveReligion();
		bssNew.savePlace();
		bssNew.getEntityManager().getTransaction().commit();
		System.out.println("done with master data......");
	}

	protected void save() throws Exception {
		List<MedicalProblem> medicalProblems = bssNew.findAllMedicalProblems();
		List<Room> rooms = bssNew.findAllRooms();
		List<Paymentsmade> paymentsMade = bssOld.findAllPaymentsMade();
		List<RoomAllocation> oldRoomAllocations = bssOld
				.findAllOldRoomAllocations();
		List<Relationship> relationships = bssNew.findAllRelationships();
		List<IdCardType> idCardTypes = bssNew.findAllIdCardTypes();
		List<Profession> professions = bssNew.findAllProfessions();
		Place place = bssNew.getPlace();
		Religion religion = bssNew.getReligion();
		List<PatientRecord> patientRecords = bssOld.findAllPatientRecords();
		int patientId = 0;
		List<Patient> patients = new ArrayList<Patient>();
		Set<Attendent> attendents = new HashSet<Attendent>();
		List<CurrentAttendent> currentAttendents = new ArrayList<CurrentAttendent>();
		float i = 0, size = patientRecords.size();
		try {
			for (PatientRecord patientRecord : patientRecords) {
				patientId = patientRecord.getPatientId();
				Patient patient = bssNew.savePatient(patients, patientRecord,
						idCardTypes, professions, place, religion);

				Admission admission = getCurrentAdmission(patient,
						patientRecord.getPatientId(), medicalProblems,
						paymentsMade, oldRoomAllocations, rooms, idCardTypes,
						relationships);
				bssNew.saveAdmission(admission);

				createAllAndCurrentAttendentsRecords(attendents, admission,
						currentAttendents, patientRecord.getPatientId(),
						relationships, idCardTypes, patient);

				i++;
				
				if (i % 100 == 0) {
					System.out.println("Percentage==>" + (i * 100) / size);
				}
			}
			bssNew.saveAttendents(attendents);
			bssNew.saveCurrentAttendants(currentAttendents);
		} catch (Exception e) {

			System.out.println("patientId===>" + patientId);

			e.printStackTrace();
			throw e;
		}
	}

	public void createAllAndCurrentAttendentsRecords(Set<Attendent> attendents,
			Admission admission, List<CurrentAttendent> currentAttendents,
			int oldPatientId, List<Relationship> relationships,
			List<IdCardType> idCardTypes, Patient patient) throws Exception {

		List<AttendentRecord> attendentRecords = bssOld
				.findAllAttendentRecordsByPatientId(oldPatientId);

		for (AttendentRecord attendentRecord : attendentRecords) {
			boolean exists = false;
			Attendent attendent = new Attendent();
			attendent.setPatient(patient);
			attendent.setName(attendentRecord.getName().trim());
			if (attendentRecord.isIsPresent() && admission!=null) {
				CurrentAttendent currentAttendent = new CurrentAttendent();
				for (Attendent existingAttendent : attendents) {
					if (existingAttendent.equals(attendent)) {
						attendent = existingAttendent;
						exists = true;
						break;
					}
				}
				currentAttendent.setAttendent(attendent);
				currentAttendent.setAdmission(admission);
				currentAttendents.add(currentAttendent);
			}

			if (!exists) {
				Relationship relationship = bssNew.findRelationship(
						relationships, attendentRecord.getRelationship());
				attendent.setRelationship(relationship);
				IdCardType idcardtype = bssNew.findIdCartType(idCardTypes,
						attendentRecord.getIdType());
				attendent.setIdCardType(idcardtype);
				attendent.setIdCardNumber(attendentRecord.getIdNumber());

				attendent.setDateOfBirth(new Date());
				attendent.setSex("F");
				attendents.add(attendent);
			}
		}

	}

	protected Admission getCurrentAdmission(Patient patient, int oldPatientId,
			List<MedicalProblem> medicalProblems,
			List<Paymentsmade> paymentsMade,
			List<RoomAllocation> oldRoomAllocations, List<Room> rooms,
			List<IdCardType> idCardTypes, List<Relationship> relationships) {

		List<CheckInOut> checkInOuts = bssOld.findAllCheckInOut(oldPatientId);
		Admission admission = null;
		for (CheckInOut checkInOut : checkInOuts) {
			// TODO have to save idMaterialSet
			// checkInOut.active, exitInited

			if (checkInOut.getCheckOutTime() == null) {
				admission = new Admission();
				MedicalProblem medicalProblem = bssNew.findMedicalProblem(
						medicalProblems, checkInOut.getPatient()
								.getMedicalProblem());
				admission.setMedicalProblem(medicalProblem);
				admission.setDateOfAdmission(checkInOut.getCheckInTime());
				admission.setDateOfExit(checkInOut.getCheckOutTime());
				/*
				 * admission.setTownOfLastDeparture(checkInOut
				 * .getTownOfLastDeparture());
				 */
				admission.setDateFrom(checkInOut.getDateOfStay());
				admission.setDateTo(checkInOut.getExtDateOfStay());
				admission.setCaseNo(checkInOut.getPatient().getTatacaseno());

				List<Payment> payments = bssNew.getPayments(
						checkInOut.getTransactionId(), paymentsMade, admission);
				Payment admissionPayment = bssNew.getAdmissionPayment(
						admission, checkInOut);
				payments.add(admissionPayment);
				admission.setPayments(payments);
				admission.setPatient(patient);
				List<RoomBooking> roomBookings = bssNew.getRoomBookings(
						checkInOut, oldRoomAllocations, rooms, admission);
				admission.setRoomBookings(roomBookings);
			}
		}
		return admission;

	}

}
